<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title>Analog-to-Digital Converters (ADCs)</title>
<meta name="author" content="Jan-Hinrich Hauer, Philip Levis, Vlado Handziski, David Gay" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2009/02/03 23:07:32 $
:version: $Revision: 1.11 $
:copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
*/
body {
  font-family: Times;
  font-size: 16px;
}

.first {
  margin-top: 0 ! important }

.last {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dd {
  margin-bottom: 0.5em }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning, div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title,
div.admonition p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 0em 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1 {
  font-family: Arial, sans-serif;
  font-size: 20px;
}

h1.title {
 text-align: center;
 font-size: 32px;
}

h2 {
 font-size: 16px;
 font-family: Arial, sans-serif;
}

h2.subtitle {
  text-align: center }

h3 {
 font-size: 12px;
 font-family: Arial, sans-serif;
}

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee;
  border-color: #000000;
  border-width: thin; 
  font-size: 14px
}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em;
}

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap;
  }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {}

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="analog-to-digital-converters-adcs">
<h1 class="title">Analog-to-Digital Converters (ADCs)</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">TEP:</th><td class="field-body">101</td>
</tr>
<tr class="field"><th class="docinfo-name">Group:</th><td class="field-body">Core Working Group</td>
</tr>
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
<td>Final</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Jan-Hinrich Hauer, Philip Levis, Vlado Handziski, David Gay</td></tr>
</tbody>
</table>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">This memo documents a part of TinyOS for the TinyOS Community, and
requests discussion and suggestions for improvements.  Distribution
of this memo is unlimited. This memo is in full compliance with
<a class="citation-reference" href="#tep1" id="id1" name="id1">[TEP1]</a>.</p>
</div>
<div class="section">
<h1><a id="abstract" name="abstract">Abstract</a></h1>
<p>This TEP proposes a hardware abstraction for analog-to-digital converters (ADCs)
in TinyOS 2.x, which is aligned to the three-layer Hardware Abstraction
Architecture (HAA) specified in <a class="citation-reference" href="#tep2" id="id2" name="id2">[TEP2]</a>. It describes some design principles and
documents the set of hardware-independent interfaces to an ADC.</p>
</div>
<div class="section">
<h1><a id="introduction" name="introduction">1. Introduction</a></h1>
<p>Analog-to-digital converters (ADCs) are devices that convert analog input
signals to discrete digital output signals, typically voltage to a binary
number.  The interested reader can refer to Appendix A for a brief overview of
the ADC hardware on some current TinyOS platforms.  In earlier versions of
TinyOS, the distinction between a sensor and an ADC were blurred: this led
components that had nothing to do with an ADC to still resemble one
programatically, even though the semantics and forms of operation were
completely different.  To compensate for the difference non-ADC sensors
introduced additional interfaces, such as <tt class="docutils literal"><span class="pre">ADCError</span></tt>, that were tightly bound
to sensor acquisition but separate in wiring. The separation between the ADC
and <tt class="docutils literal"><span class="pre">ADCError</span></tt> interface is bug prone and problematic, as is the equation of
a sensor and an ADC. TinyOS 2.x separates the structure and interfaces of an
ADC from those of sensor drivers (which may be on top of an ADC stack, but
this fact is hidden from higher level components). This TEP presents how TinyOS
2.x structures ADC software. <a class="citation-reference" href="#tep109" id="id3" name="id3">[TEP109]</a> (Sensor Boards) shows how a platform can
present actual named sensors.</p>
<p>As can be seen in Appendix A the ADC hardware used on TinyOS platforms differ
in many respects, which makes it difficult to find a chip independent
representation for an ADC. Even if there were such a representation, the
configuration details of an ADC would still depend on the actual device
producing the input signal (sensor).  Neither a platform independent
application nor the ADC hardware stack itself has access to this information,
as it can only be determined on a platform or sensorboard level. For example,
determining which ADC port a sensor is attached to and how conversion results
need to be interpreted is a platform specific determination. Although the
actual configuration details may be different the procedure of configuring an
ADC can be unified on all ADCs with the help of <strong>hardware independent
interfaces</strong>: in a similar way as the <tt class="docutils literal"><span class="pre">Read</span></tt> interface definition does not
predefine the type or semantics of the exchanged data (see <a class="citation-reference" href="#tep114" id="id4" name="id4">[TEP114]</a>), a
configuration interface definition can abstract from the data type and
semantics of the involved configuration settings.  For example, like a
component can provide a <tt class="docutils literal"><span class="pre">Read&lt;uint8_t&gt;</span></tt> or <tt class="docutils literal"><span class="pre">Read&lt;uint16_t&gt;</span></tt> interface, it
can also provide a <tt class="docutils literal"><span class="pre">AdcConfigure&lt;atm128_adc_config_t&gt;</span></tt> or
<tt class="docutils literal"><span class="pre">AdcConfigure&lt;msp430adc12_channel_config_t&gt;</span></tt> interface depending on what ADC
it represents.  This TEP proposes the (typed) <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface as the
standard interface for configuring an ADC in TinyOS 2.x.</p>
<p>In spite of their hardware differences, one aspect represents a common
denominator of ADCs: they all produce conversion results. To facilitate sensor
software development conversion results are returned by the ADC stack through
the interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadStream</span></tt> and <tt class="docutils literal"><span class="pre">ReadNow</span></tt> (see <a class="reference" href="#interfaces">2.  Interfaces</a>
and <a class="citation-reference" href="#tep114" id="id5" name="id5">[TEP114]</a>).  Conversion results are returned as uninterpreted values and
translating them to engineering units can only be done with the configuration
knowledge of the respective platform, for example, the reference voltage or the
resistance of a reference resistor in ratiometric measurements.  Translating
uninterpreted values to engineering units may be performed by components
located on top of the ADC stack and is out of the scope of this TEP.</p>
<p>The top layer of abstraction of an ADC - the Hardware Interface Layer (HIL) -
thus provides the interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt> and uses
the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface for hardware configuration (why it <strong>uses</strong> and
does not <strong>provide</strong> <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> is explained below).  Since the type and
semantics of the parameters passed through these interfaces is dependent on the
actual ADC implementation, it is only a &quot;weak&quot; HIL (see <a class="citation-reference" href="#tep2" id="id6" name="id6">[TEP2]</a>).</p>
<p>Following the principles of the HAA <a class="citation-reference" href="#tep2" id="id7" name="id7">[TEP2]</a> the Hardware Adaptation Layer (HAL,
which resides below the HIL) of an ADC should expose all the chip-specific
capabilities of the chip.  For example, the ADC12 on the MSP430 MCU supports a
&quot;Repeat-Sequence-of-Channels Mode&quot; and therefore this function should be
accessible on the HAL of the MSP430 ADC12 hardware abstraction.  Other ADCs
might not exhibit such functionality and might therefore - on the level of HAL
- provide only an interface to perform single conversions. Since all ADCs have
the same HIL representation it may be necessary to perform some degree of
software emulation in the HIL implementation.  For example, a <tt class="docutils literal"><span class="pre">ReadStream</span></tt>
command can be emulated by multiple single conversion commands. Below the HAL
resides the Hardware Presentation Layer (HPL), a stateless component that
provides access to the hardware registers (see <a class="citation-reference" href="#tep2" id="id8" name="id8">[TEP2]</a>). The general structure
(without virtualization) of the ADC stack is as follows</p>
<pre class="literal-block">
       ^                     |
       |                     |
       |                   Read,
 AdcConfigure              ReadNow (+ Resource),
       |                   ReadStream
       |                     |
       |                     V
 +----------------------------------+
 |  Hardware Interface Layer (HIL)  |
 |  (chip-specific implementation)  |
 +----------------------------------+
                  |
                  |
   chip-specific interface(s) + Resource
(e.g. Msp430Adc12SingleChannel + Resource)
                  |
                  V
 +----------------------------------+
 |  Hardware Adaptation Layer (HAL) |
 |  (chip-specific implementation)  |
 +----------------------------------+
                  |
                  |
        chip-specific interface(s)
            (e.g. HplAdc12)
                  |
                  V
 +----------------------------------+
 | Hardware Presentation Layer (HPL)|
 | (chip-specific implementation)   |
 +----------------------------------+
</pre>
<p>The rest of this TEP specifies:</p>
<ul class="simple">
<li>the set of standard TinyOS interfaces for collecting ADC conversion
results and for configuring an ADC (<a class="reference" href="#interfaces">2. Interfaces</a>)</li>
<li>guidelines on how an ADC's HAL should expose chip-specific
interfaces (<a class="reference" href="#hal-guidelines">3. HAL guidelines</a>)</li>
<li>what components an ADC's HIL MUST implement (<a class="reference" href="#hil-requirements">4. HIL requirements</a>)</li>
<li>guidelines on how the HIL should be implemented
(<a class="reference" href="#hil-guidelines">5. HIL guidelines</a>)</li>
<li>a section pointing to current implementations (<a class="reference" href="#implementation">6. Implementation</a>)</li>
</ul>
<p>This TEP ends with appendices documenting, as an example, the ADC implementation
for the TI MSP430 MCU.</p>
</div>
<div class="section">
<h1><a id="interfaces" name="interfaces">2. Interfaces</a></h1>
<p>This TEP proposes the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface for ADC hardware configuration
and the <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadStream</span></tt> and <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interfaces to acquire
conversion results. The <tt class="docutils literal"><span class="pre">Read</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interfaces are documented
in <a class="citation-reference" href="#tep114" id="id9" name="id9">[TEP114]</a> and the <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is documented in this TEP.  A
<tt class="docutils literal"><span class="pre">Read[Now|Stream]</span></tt> interface is always provided in conjunction with a
<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
<div class="section">
<h2><a id="interface-for-configuring-the-adc-hardware" name="interface-for-configuring-the-adc-hardware">Interface for configuring the ADC hardware</a></h2>
<p>The <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is defined as follows:</p>
<pre class="literal-block">
interface AdcConfigure&lt; config_type &gt;
{
  async command config_type getConfiguration();
}
</pre>
<p>This interface is used by the ADC stack to retrieve the hardware configuration
of an ADC HIL client. <tt class="docutils literal"><span class="pre">config_type</span></tt> is a chip-specific data type (simple or
structured) that contains all information necessary to configure the respective
ADC hardware. For example, on the ADC12 of the MSP430 the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt>
interface will be instantiated with the <tt class="docutils literal"><span class="pre">const</span> <span class="pre">msp430adc12_channel_config_t*</span></tt>
data type. A client MUST always return the same configuration through a
<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface and, if configuration data is passed as a pointer,
the HIL component (see <a class="reference" href="#hil-requirements">4. HIL requirements</a>) MUST NOT reference it after the
return of the <tt class="docutils literal"><span class="pre">getConfiguration()</span></tt> command. If a client wants to use the ADC
with different configurations it must provide multiple instances of the
<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
<p>Note that the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is <strong>provided</strong> by an ADC HIL client
and it is <strong>used</strong> by the ADC HIL implementation. Therefore an ADC HIL client
cannot initiate the configuration of the ADC hardware itself. Instead it is the
ADC HIL implementation that can &quot;pull&quot; the client's ADC configuration just
before it initates a conversion based on the respective client's configuration.
The rationale is that the ADC HIL implementation does not have to store an ADC
configuration per client - instead the ADC client can, for example, store its
configuration in program memory.</p>
</div>
<div class="section">
<h2><a id="interfaces-for-acquiring-conversion-results" name="interfaces-for-acquiring-conversion-results">Interfaces for acquiring conversion results</a></h2>
<p>This TEP proposes to adopt the following two source-independent data
collection interfaces from <a class="citation-reference" href="#tep114" id="id10" name="id10">[TEP114]</a> for the collection of ADC conversion
results on the level of HIL:</p>
<pre class="literal-block">
interface Read&lt; size_type &gt;
interface ReadStream&lt; size_type &gt;
</pre>
<p>In addition it proposes the following data collection interface for low-latency
reading of conversion results:</p>
<pre class="literal-block">
interface ReadNow&lt; size_type &gt;
</pre>
<p>Every data collection interface is associated with an <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt>
interface (how this association is realized is explained in Section <a class="reference" href="#hil-requirements">4.  HIL
requirements</a>).  As the resolution of conversion results is chip-specific, the
<tt class="docutils literal"><span class="pre">size_type</span></tt> parameter reflects an upper bound for the chip-specific
resolution of the conversion results - the actual resolution may be smaller
(e.g.  uint16_t for a 12-bit ADC).</p>
<div class="section">
<h3><a id="read" name="read">Read</a></h3>
<p>The <tt class="docutils literal"><span class="pre">Read</span></tt> interface can be used to sample an ADC channel once and return a
single conversion result as an uninterpreted value. The <tt class="docutils literal"><span class="pre">Read</span></tt> interface is
documented in <a class="citation-reference" href="#tep114" id="id11" name="id11">[TEP114]</a>.</p>
</div>
<div class="section">
<h3><a id="readstream" name="readstream">ReadStream</a></h3>
<p>The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface can be used to sample an ADC channel multiple
times with a specified sampling period. The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface is
documented in <a class="citation-reference" href="#tep114" id="id12" name="id12">[TEP114]</a> .</p>
</div>
<div class="section">
<h3><a id="readnow" name="readnow">ReadNow</a></h3>
<p>The <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is intended for split-phase low-latency
reading of small values:</p>
<pre class="literal-block">
interface ReadNow&lt;val_t&gt;
{
  async command error_t read();
  async event void readDone( error_t result, val_t val );
}
</pre>
<p>This interface is similar to the <tt class="docutils literal"><span class="pre">Read</span></tt> interface, but works in asynchronous
context. A successful call to <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> means that the ADC hardware
has started the sampling process and that <tt class="docutils literal"><span class="pre">ReadNow.readDone()</span></tt> will be
signalled once it has finished (note that the asynchronous
<tt class="docutils literal"><span class="pre">ReadNow.readDone()</span></tt> might be signalled even before the call to
<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> has returned).  Due to its timing constraints the
<tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is always provided in conjunction with an instance of the
<tt class="docutils literal"><span class="pre">Resource</span></tt> interface and a client must reserve the ADC through the
<tt class="docutils literal"><span class="pre">Resource</span></tt> interface before the client may call <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt>.  Please
refer to <a class="citation-reference" href="#tep108" id="id13" name="id13">[TEP108]</a> on how the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface should be used by a client
component.</p>
</div>
</div>
</div>
<div class="section">
<h1><a id="hal-guidelines" name="hal-guidelines">3. HAL guidelines</a></h1>
<p>As explained in <a class="reference" href="#introduction">1. Introduction</a> the HAL exposes the full capabilities of the
ADC hardware. Therefore only chip- and platform-dependent clients can wire to
the HAL. Although the HAL is chip-specific, both, in terms of implementation
and representation, its design should follow the guidelines described in this
section to facilitate the mapping to the HIL representation. Appendix B shows
the signature of the HAL for the MSP430.</p>
<div class="section">
<h2><a id="resource-reservation" name="resource-reservation">Resource reservation</a></h2>
<p>As the ADC hardware is a shared resource that is usually multiplexed between
several clients some form of access arbitration is necessary.  The HAL should
therefore provide a parameterized <tt class="docutils literal"><span class="pre">Resource</span></tt> interface, instantiate a
standard arbiter component and connect the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface to the
arbiter as described in <a class="citation-reference" href="#tep108" id="id14" name="id14">[TEP108]</a>. To ensure fair and uniform arbitration on
all platforms the standard round robin arbiter is recommended. Resource
arbiters and the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface are the topic of <a class="citation-reference" href="#tep108" id="id15" name="id15">[TEP108]</a>.</p>
</div>
<div class="section">
<h2><a id="configuration-and-sampling" name="configuration-and-sampling">Configuration and sampling</a></h2>
<p>As the ADC hardware is a shared resource the HAL should support hardware
configuration and sampling per client (although per-port configuration is
possible, it is not recommended, because it forces all clients to use the same
configuration for a given port).  Therefore the HAL should provide sampling
interfaces parameterized by a client identifier. A HAL client can use its
instance of the sampling interface to configure the ADC hardware, start the
sampling process and acquire conversion results. It wires to a sampling
interface using a unique client identifier (this may be hidden by a
virtualization component). All commands and events in the sampling interface
should be 'async' to reflect the potential timing requirements of clients on
the level of HAL. A HAL may provide multiple different parameterized sampling
interfaces, depending on the hardware capabilities.  This allows to
differentiate/group ADC functionality, for example single vs.  repeated
sampling, single channel vs.  multiple channels or low-frequency vs.
high-frequency sampling.  Every sampling interface should allow the client to
individually configure the ADC hardware, for example by including the
configuration data as parameters in the sampling commands.  However, if
configuration data is passed as a pointer, the HAL component MUST NOT reference
it after the return of the respective command.  Appendix B shows the HAL
interfaces for the MSP430.</p>
</div>
<div class="section">
<h2><a id="hal-virtualization" name="hal-virtualization">HAL virtualization</a></h2>
<p>In order to hide wiring complexities and/or export only a subset of all ADC
functions generic ADC wrapper components may be provided on the level of HAL.
Such components can also be used to ensure that a sampling interface is always
provided with a <tt class="docutils literal"><span class="pre">Resource</span></tt> interface and both are instantiated with the same
client ID if this is required by the HAL implementation.</p>
</div>
</div>
<div class="section">
<h1><a id="hil-requirements" name="hil-requirements">4. HIL requirements</a></h1>
<p>The following generic components MUST be provided on all platforms that have an
ADC:</p>
<pre class="literal-block">
AdcReadClientC
AdcReadNowClientC
AdcReadStreamClientC
</pre>
<p>These components provide virtualized access to the HIL of an ADC. They are
instantiated by an ADC client and provide/use the four interfaces described in
Section <a class="reference" href="#interfaces">2.  Interfaces</a>. An ADC client may instantiate multiple such
components. The following paragraphs describe their signatures. Note that this
TEP does not address the issue of how to deal with multiple ADCs on the same
platform (the question of how to deal with multiple devices of the same class
is a general one in TinyOS 2.x). Appendix C shows the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt> for
the MSP430.</p>
<div class="section">
<h2><a id="adcreadclientc" name="adcreadclientc">AdcReadClientC</a></h2>
<pre class="literal-block">
generic configuration AdcReadClientC() {
  provides {
    interface Read&lt; size_type &gt;;
  }
  uses {
    interface AdcConfigure&lt; config_type &gt;;
  }
}
</pre>
<p>The <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt> component provides a <tt class="docutils literal"><span class="pre">Read</span></tt> interface for acquiring
single conversion results. The associated ADC channel (port) and further
configuration details are returned by the <tt class="docutils literal"><span class="pre">AdcConfigure.getConfiguration()</span></tt>
command. It is the task of the client to wire this interface to a component
that provides the client's ADC configuration. The HIL implementation will use
the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface to dynamically &quot;pull&quot; the client's ADC settings
when it translates the <tt class="docutils literal"><span class="pre">Read.read()</span></tt> command to a chip-specific sampling
command.  Note that both, <tt class="docutils literal"><span class="pre">size_type</span></tt> and <tt class="docutils literal"><span class="pre">config_type</span></tt>, are only
placeholders and will be instantiated by the respective HIL implementation (for
an example, see the AdcReadClientC for the MSP430 in Appendix C).</p>
</div>
<div class="section">
<h2><a id="adcreadnowclientc" name="adcreadnowclientc">AdcReadNowClientC</a></h2>
<pre class="literal-block">
generic configuration AdcReadNowClientC() {
  provides {
    interface Resource;
    interface ReadNow&lt; size_type &gt;;
  }
  uses {
    interface AdcConfigure&lt; config_type &gt;;
  }
}
</pre>
<p>The <tt class="docutils literal"><span class="pre">AdcReadNowClientC</span></tt> component provides a <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface for
acquiring single conversion results. In contrast to <tt class="docutils literal"><span class="pre">Read.read()</span></tt> when a call
to <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> succeeds, the ADC starts to sample the channel
immediately (a successful <tt class="docutils literal"><span class="pre">Read.read()</span></tt> command may not have this
implication, see <a class="citation-reference" href="#tep114" id="id16" name="id16">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>). A client MUST reserve the ADC
through the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface before the client may call
<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> and it MUST release the ADC through the <tt class="docutils literal"><span class="pre">Resource</span></tt>
interface when it no longer needs to access it (for more details on how to use
the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface please refer to <a class="citation-reference" href="#tep108" id="id17" name="id17">[TEP108]</a>).  The associated ADC
channel (port) and further configuration details are returned by the
<tt class="docutils literal"><span class="pre">AdcConfigure.getConfiguration()</span></tt> command. It is the task of the client to
wire this interface to a component that provides the client's ADC
configuration.  The HIL implementation will use the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface
to dynamically &quot;pull&quot; the client's ADC settings when it translates the
<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> command to a chip-specific sampling command. Note that both,
<tt class="docutils literal"><span class="pre">size_type</span></tt> and <tt class="docutils literal"><span class="pre">config_type</span></tt>, are only placeholders and will be
instantiated by the respective HIL implementation (for an example how this is
done for the AdcReadClientC see Appendix C).</p>
</div>
<div class="section">
<h2><a id="adcreadstreamclientc" name="adcreadstreamclientc">AdcReadStreamClientC</a></h2>
<pre class="literal-block">
generic configuration AdcReadStreamClientC() {
  provides {
    interface ReadStream&lt; size_type &gt;;
  }
  uses {
    interface AdcConfigure&lt; config_type&gt;;
  }
}
</pre>
<p>The <tt class="docutils literal"><span class="pre">AdcReadStreamClientC</span></tt> component provides a <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface for
acquiring multiple conversion results at once. The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface is
explained in <a class="citation-reference" href="#tep114" id="id18" name="id18">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>. The <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is
used in the same way as described in the section on the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt>.
Note that both, <tt class="docutils literal"><span class="pre">size_type</span></tt> and <tt class="docutils literal"><span class="pre">config_type</span></tt>, are only placeholders and
will be instantiated by the respective HIL implementation (for an example how
this is done for the AdcReadClientC see Appendix C).</p>
</div>
</div>
<div class="section">
<h1><a id="hil-guidelines" name="hil-guidelines">5. HIL guidelines</a></h1>
<p>The HIL implementation of an ADC stack has two main tasks: it translates a
<tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> or <tt class="docutils literal"><span class="pre">ReadStream</span></tt> request to a chip-specific HAL sampling
command and it abstracts from the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface (the latter only for
the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt> and <tt class="docutils literal"><span class="pre">AdcReadStreamClientC</span></tt>). The first task is solved
with the help of the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface which is used by the HIL
implementation to retrieve a client's ADC configuration.  The second task MAY
be performed by the following library components: <tt class="docutils literal"><span class="pre">ArbitratedReadC</span></tt>, and
<tt class="docutils literal"><span class="pre">ArbitratedReadStreamC</span></tt> (in tinyos-2.x/tos/system) - please refer to the
Atmel Atmega 128 HAL implementation (in tinyos-2.x/tos/chips/atm128/adc) for an
example.  Note that since the <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is always provided in
conjunction with a <tt class="docutils literal"><span class="pre">Resource</span></tt> interface the HIL implementation does not have
to perform the ADC resource reservation for an <tt class="docutils literal"><span class="pre">AdcReadNowClientC</span></tt>, but may
simply forward an instance of the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface from the HAL to the
<tt class="docutils literal"><span class="pre">AdcReadNowClientC</span></tt>.</p>
<p>The typical sequence of events is as follows: when a client requests data
through the <tt class="docutils literal"><span class="pre">Read</span></tt> or <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface the HIL will request access to
the HAL using the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface.  After the HIL has been granted
access, it will &quot;pull&quot; the client's ADC configuration using the
<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface and translate the client's <tt class="docutils literal"><span class="pre">Read</span></tt> or
<tt class="docutils literal"><span class="pre">ReadStream</span></tt> command to a chip-specific HAL command. Once the HIL is
signalled the conversion result(s) from the HAL it releases the ADC through the
<tt class="docutils literal"><span class="pre">Resource</span></tt> interface and signals the conversion result(s) to the client
though the <tt class="docutils literal"><span class="pre">Read</span></tt> or <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface.  When a client requests data
through the <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface the HIL translates the client's command to
the chip-specific HAL command without using the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface (it may
check ownership of the client through the <tt class="docutils literal"><span class="pre">ArbiterInfo</span></tt> interface - this
check can also be done in the HAL implementation). Once the HIL is signalled
the conversion result(s) it forwards it to the respective <tt class="docutils literal"><span class="pre">ReadNow</span></tt> client.</p>
</div>
<div class="section">
<h1><a id="implementation" name="implementation">6. Implementation</a></h1>
<div class="section">
<h2><a id="testadc-application" name="testadc-application">TestAdc application</a></h2>
<p>An ADC HIL test application can be found in <tt class="docutils literal"><span class="pre">tinyos-2.x/apps/tests/TestAdc</span></tt>.
Note that this application instantiates generic DemoSensorC, DemoSensorStreamC
and DemoSensorNowC components (see <a class="citation-reference" href="#tep114" id="id19" name="id19">[TEP114]</a>) and assumes that these components
are actually wired to an ADC HIL. Please refer to
<tt class="docutils literal"><span class="pre">tinyos-2.x/apps/tests/TestAdc/README.txt</span></tt> for more information.</p>
</div>
<div class="section">
<h2><a id="haa-on-the-msp430-and-atmega-128" name="haa-on-the-msp430-and-atmega-128">HAA on the MSP430 and Atmega 128</a></h2>
<p>The implementation of the ADC12 stack on the MSP430 can be found in
<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/msp430/adc12</span></tt>:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">HplAdc12P.nc</span></tt> is the HPL implementation</li>
<li><tt class="docutils literal"><span class="pre">Msp430Adc12P.nc</span></tt> is the HAL implementation</li>
<li><tt class="docutils literal"><span class="pre">AdcP.nc</span></tt> is the HIL implementation</li>
<li><tt class="docutils literal"><span class="pre">AdcReadClientC.nc</span></tt>, <tt class="docutils literal"><span class="pre">AdcReadNowClientC.nc</span></tt> and
<tt class="docutils literal"><span class="pre">AdcReadStreamClientC.nc</span></tt> provide virtualized access to the HIL</li>
<li>the use of DMA or the reference voltage generator and the
HAL virtualization components are explained in <tt class="docutils literal"><span class="pre">README.txt</span></tt></li>
</ul>
</blockquote>
<p>The Atmel Atmega 128 ADC implementation can be found in
<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/atm128/adc</span></tt>:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">HplAtm128AdcC.nc</span></tt> is the HPL implementation</li>
<li><tt class="docutils literal"><span class="pre">Atm128AdcP.nc</span></tt> is the HAL implementation</li>
<li><tt class="docutils literal"><span class="pre">AdcP.nc</span></tt>, <tt class="docutils literal"><span class="pre">WireAdcP.nc</span></tt> and the library components for arbitrating
'Read', 'ReadNow' and 'ReadStream', <tt class="docutils literal"><span class="pre">ArbitratedReadC</span></tt> and
<tt class="docutils literal"><span class="pre">ArbitratedReadStreamC</span></tt> (in <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/system</span></tt>), realize
the HIL</li>
<li><tt class="docutils literal"><span class="pre">AdcReadClientC.nc</span></tt>, <tt class="docutils literal"><span class="pre">AdcReadNowClientC.nc</span></tt> and
<tt class="docutils literal"><span class="pre">AdcReadStreamClientC.nc</span></tt> provide virtualized access to the HIL</li>
</ul>
</blockquote>
</div>
</div>
<div class="section">
<h1><a id="appendix-a-hardware-differences-between-platforms" name="appendix-a-hardware-differences-between-platforms">Appendix A: Hardware differences between platforms</a></h1>
<p>The following table compares the characteristics of two microcontrollers
commonly used in TinyOS platforms:</p>
<table border="1" class="docutils">
<colgroup>
<col width="34%" />
<col width="34%" />
<col width="32%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">&nbsp;</th>
<th class="head">Atmel Atmega 128</th>
<th class="head">TI MSP430 ADC12</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Resolution</td>
<td>10-bit</td>
<td>12-bit</td>
</tr>
<tr><td>channels</td>
<td><ul class="first last simple">
<li>8 multiplexed
external channels</li>
<li>16 differential
voltage input
combinations</li>
<li>2 differential
inputs with gain
amplification</li>
</ul>
</td>
<td><ul class="first last simple">
<li>8 individually
configurable
external channels</li>
<li>internal channels
(AVcc, temperature,
reference voltages)</li>
</ul>
</td>
</tr>
<tr><td>internal reference
voltage</td>
<td>2.56V</td>
<td>1.5V or 2.5V</td>
</tr>
<tr><td>conversion reference</td>
<td><ul class="first last simple">
<li>positive terminal:
AVcc or 2.56V  or
AREF (external)</li>
<li>negative terminal:
GND</li>
</ul>
</td>
<td><blockquote class="first">
individually
selectable per
channel:</blockquote>
<ul class="last simple">
<li>AVcc and AVss</li>
<li>Vref+ and AVss</li>
<li>Veref+ and AVss</li>
<li>AVcc and (Vref- or
Veref-)</li>
<li>AVref+ and (Vref-
or Veref-)</li>
<li>Veref+ and (Vref-
or Veref-)</li>
</ul>
</td>
</tr>
<tr><td>conversion modes</td>
<td><ul class="first last simple">
<li>single channel
conversion mode</li>
<li>free running mode
(channels and
reference voltages
can be switched
between samples)</li>
</ul>
</td>
<td><ul class="first last simple">
<li>single conversion
mode</li>
<li>repeat single
conversion mode</li>
<li>sequence mode
(sequence &lt;= 16
channels)</li>
<li>repeat sequence
mode</li>
</ul>
</td>
</tr>
<tr><td>conversion clock
source</td>
<td>clkADC with prescaler</td>
<td>ACLK, MCLK, SMCLK or
ADC-oscillator (5MHz)
with prescaler
respectively</td>
</tr>
<tr><td>sample-hold-time</td>
<td>1.5 clock cycles
(fixed)</td>
<td>selectable values
from 4 to 1024 clock
cycles</td>
</tr>
<tr><td>conversion triggering</td>
<td>by software</td>
<td>by software or timers</td>
</tr>
<tr><td>conversion during
sleep mode possible</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr><td>interrupts</td>
<td>after each conversion</td>
<td>after single or
sequence conversion</td>
</tr>
</tbody>
</table>
</div>
<div class="section">
<h1><a id="appendix-b-a-hal-representation-msp430-adc12" name="appendix-b-a-hal-representation-msp430-adc12">Appendix B: a HAL representation: MSP430 ADC12</a></h1>
<p>This section shows the HAL signature for the ADC12 of the TI MSP430 MCU. It
reflects the four MSP430 ADC12 conversion modes as it lets a client sample an
ADC channel once (&quot;Single-channel-single-conversion&quot;) or repeatedly
(&quot;Repeat-single-channel&quot;), multiple times (&quot;Sequence-of-channels&quot;) or multiple
times repeatedly (&quot;Repeat-sequence-of-channels&quot;). In contrast to the single
channel conversion modes the sequence conversion modes trigger a single
interrupt after multiple samples and thus enable high-frequency sampling. The
<tt class="docutils literal"><span class="pre">DMAExtension</span></tt> interface is used to reset the state machine when the DMA is
responsible for data transfer (managed in an exterior component):</p>
<pre class="literal-block">
configuration Msp430Adc12P
{
  provides {
    interface Resource[uint8_t id];
    interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
    interface AsyncStdControl as DMAExtension[uint8_t id];
  }
}

interface Msp430Adc12SingleChannel
{
  async command error_t configureSingle(const msp430adc12_channel_config_t *config);
  async command error_t configureSingleRepeat(const msp430adc12_channel_config_t *config, uint16_t jiffies);
  async command error_t configureMultiple( const msp430adc12_channel_config_t *config, uint16_t buffer[], uint16_t numSamples, uint16_t jiffies);
  async command error_t configureMultipleRepeat(const msp430adc12_channel_config_t *config, uint16_t buffer[], uint8_t numSamples, uint16_t jiffies);
  async command error_t getData();
  async event error_t singleDataReady(uint16_t data);
  async event uint16_t* multipleDataReady(uint16_t buffer[], uint16_t numSamples);
}

typedef struct
{
  unsigned int inch: 4;            // input channel
  unsigned int sref: 3;            // reference voltage
  unsigned int ref2_5v: 1;         // reference voltage level
  unsigned int adc12ssel: 2;       // clock source sample-hold-time
  unsigned int adc12div: 3;        // clock divider sample-hold-time
  unsigned int sht: 4;             // sample-hold-time
  unsigned int sampcon_ssel: 2;    // clock source sampcon signal
  unsigned int sampcon_id: 2;      // clock divider sampcon signal
} msp430adc12_channel_config_t;
</pre>
</div>
<div class="section">
<h1><a id="appendix-c-a-hil-representation-msp430-adc12" name="appendix-c-a-hil-representation-msp430-adc12">Appendix C: a HIL representation: MSP430 ADC12</a></h1>
<p>The signature of the AdcReadClientC component for the MSP430 ADC12 is as
follows:</p>
<pre class="literal-block">
generic configuration AdcReadClientC() {
  provides interface Read&lt;uint16_t&gt;;
  uses interface AdcConfigure&lt;const msp430adc12_channel_config_t*&gt;;
}
</pre>
<table class="docutils citation" frame="void" id="tep1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="tep1">[TEP1]</a></td><td>TEP 1: TEP Structure and Keywords.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep2">[TEP2]</a></td><td><em>(<a class="fn-backref" href="#id2">1</a>, <a class="fn-backref" href="#id6">2</a>, <a class="fn-backref" href="#id7">3</a>, <a class="fn-backref" href="#id8">4</a>)</em> TEP 2: Hardware Abstraction Architecture.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep108" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep108">[TEP108]</a></td><td><em>(<a class="fn-backref" href="#id13">1</a>, <a class="fn-backref" href="#id14">2</a>, <a class="fn-backref" href="#id15">3</a>, <a class="fn-backref" href="#id17">4</a>)</em> TEP 108: Resource Arbitration.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep109" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3" name="tep109">[TEP109]</a></td><td>TEP 109: Sensor Boards.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep114" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep114">[TEP114]</a></td><td><em>(<a class="fn-backref" href="#id4">1</a>, <a class="fn-backref" href="#id5">2</a>, <a class="fn-backref" href="#id9">3</a>, <a class="fn-backref" href="#id10">4</a>, <a class="fn-backref" href="#id11">5</a>, <a class="fn-backref" href="#id12">6</a>, <a class="fn-backref" href="#id16">7</a>, <a class="fn-backref" href="#id18">8</a>, <a class="fn-backref" href="#id19">9</a>)</em> TEP 114: SIDs: Source and Sink Independent Drivers.</td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
